#!/usr/bin/python
# -*- coding: utf-8 -*-

#This file is part of pyLot library.
#
# pyLot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyLot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pyLot.  If not, see <http://www.gnu.org/licenses/>.

__author__ = u'Pierre Puiseux, Guillaume Baty'
__copyright__ = u"Copyright 2011-2012 (C) andheo, Université de Pau et des Pays de l'Adour"
__credits__ = [u'Pierre Puiseux', u'Guillaume Baty']
__license__ = "GNU Lesser General Public License"

__all__ = [u'ILogger']

from traits.api import Interface

class ILogger(Interface):
  u"""
  ILogger provides logging.Logger API and specific methods :
    - write
    - clear
    - popup.
    
  This class can be used to log and display all textual data.

  logging.Logger description:
  
  Instances of the Logger class represent a single logging channel. A
  "logging channel" indicates an area of an application. Exactly how an
  "area" is defined is up to the application developer. Since an
  application can have any number of areas, logging channels are identified
  by a unique string. Application areas can be nested (e.g. an area
  of "input processing" might include sub-areas "read CSV files", "read
  XLS files" and "read Gnumeric files"). To cater for this natural nesting,
  channel names are organized into a namespace hierarchy where levels are
  separated by periods, much like the Java or Python package namespace. So
  in the instance given above, channel names might be "input" for the upper
  level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
  There is no arbitrary limit to the depth of nesting.
  """
  # ============================================================================
  # ILogger specific methods
  # ============================================================================

  def __init__(self, name, level=None):
    pass

  def clear(self):
    u"""
    Clear (ie, remove all text)
    """

  def write (self, text, style=u'std'):
    u"""Write the unicode string's to the stream.
    Generally, this method redirects text to "info" or "stdout" method
    """

  def popup(self, title, desc=None, message=None):
    u"""
    Message used to alert user
    """

  def stdout(self, s):
    u"""
    message sent to stdout by process.
    Generally redirected to sys.stdout
    """

  def stderr(self, s):
    u"""
    message sent to stderr by process
    Generally redirected to sys.stderr
    """

  # ============================================================================
  # logging.Logger methods
  # ============================================================================

  def setLevel(self, level):
    """
    Set the logging level of this logger.
    """

  def debug(self, msg, *args, **kwargs):
    """
    Log 'msg % args' with severity 'DEBUG'.

    To pass exception information, use the keyword argument exc_info with
    a true value, e.g.

    logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
    """

  def info(self, msg, *args, **kwargs):
    """
    Log 'msg % args' with severity 'INFO'.

    To pass exception information, use the keyword argument exc_info with
    a true value, e.g.

    logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
    """

  def warning(self, msg, *args, **kwargs):
    """
    Log 'msg % args' with severity 'WARNING'.

    To pass exception information, use the keyword argument exc_info with
    a true value, e.g.

    logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
    """

  def error(self, msg, *args, **kwargs):
    """
    Log 'msg % args' with severity 'ERROR'.

    To pass exception information, use the keyword argument exc_info with
    a true value, e.g.

    logger.error("Houston, we have a %s", "major problem", exc_info=1)
    """

  def exception(self, msg, *args):
    """
    Convenience method for logging an ERROR with exception information.
    """

  def critical(self, msg, *args, **kwargs):
    """
    Log 'msg % args' with severity 'CRITICAL'.

    To pass exception information, use the keyword argument exc_info with
    a true value, e.g.

    logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
    """

  def log(self, level, msg, *args, **kwargs):
    """
    Log 'msg % args' with the integer severity 'level'.

    To pass exception information, use the keyword argument exc_info with
    a true value, e.g.

    logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
    """

  def findCaller(self):
    """
    Find the stack frame of the caller so that we can note the source
    file name, line number and function name.
    """

  def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
      """
      A factory method which can be overridden in subclasses to create
      specialized LogRecords.
      """

  def _log(self, level, msg, args, exc_info=None, extra=None):
    """
    Low-level logging routine which creates a LogRecord and then calls
    all the handlers of this logger to handle the record.
    """

  def handle(self, record):
    """
    Call the handlers for the specified record.

    This method is used for unpickled records received from a socket, as
    well as those created locally. Logger-level filtering is applied.
    """

  def addHandler(self, hdlr):
    """
    Add the specified handler to this logger.
    """

  def removeHandler(self, hdlr):
    """
    Remove the specified handler from this logger.
    """

  def callHandlers(self, record):
    """
    Pass a record to all relevant handlers.

    Loop through all handlers for this logger and its parents in the
    logger hierarchy. If no handler was found, output a one-off error
    message to sys.stderr. Stop searching up the hierarchy whenever a
    logger with the "propagate" attribute set to zero is found - that
    will be the last logger whose handlers are called.
    """

  def getEffectiveLevel(self):
    """
    Get the effective level for this logger.

    Loop through this logger and its parents in the logger hierarchy,
    looking for a non-zero logging level. Return the first one found.
    """

  def isEnabledFor(self, level):
    """
    Is this logger enabled for level 'level'?
    """


if __name__ == '__main__':
  import doctest
  doctest.testmod()
